/*
 * @Author: c
 * @Date: 2023-12-22 14:05:59
 * @LastEditTime: 2023-12-22 14:20:29
 * @LastEditors: c
 * @Description: 
 * @FilePath: \music-web-backend\src\casl\casl-ability.factory.ts
 * https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import { Inject, Injectable } from "@nestjs/common";
import { Ability, AbilityBuilder, ExtractSubjectType, InferSubjects, MongoAbility, createMongoAbility } from '@casl/ability';
import { User } from "src/core/system/user/entities/user.entity";

type Actions = 'read' | 'update';
// type Subjects = Article | typeof Article
type Subjects = any



type AppAbility = MongoAbility<[Actions, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
    createForUser(user: User) {
        const { can, build } = new AbilityBuilder<AppAbility>(createMongoAbility);

        // can('read', Article);
        can('read', User)

        const ability = build({
            detectSubjectType: object => object.constructor
        });

        // if (user.isAdmin) {
        //   can(Action.Manage, 'all'); // read-write access to everything
        // } else {
        //   can(Action.Read, 'all'); // read-only access to everything
        // }

        // can(Action.Update, Article, { authorId: user.id });
        // cannot(Action.Delete, Article, { isPublished: true });

        return build({
            // Read https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types for details
            detectSubjectType: item => item.constructor as ExtractSubjectType<any>
        });
    }
}
